Struts2运行流程

  • ActionProxy是Action的一个代理类,也就是说Action的调用时通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方法,而该方法又调用了ActionInvocation.invoke()方法
  • ActonInvocation就是Action的调用者,ActonInvocation在Action的执行过程中,负责Interceptor、Action和Result等一系列元素的调度
  • 拦截器的调用顺序是在struts-default.xml文件中的defaultStack中进行定义的

Params拦截器

Parameters拦截器将把表单字段映射到ValueStack栈的栈顶对象(此时栈顶对象即为Action)的各个属性中,如果某个字段在模型里没有匹配的属性,Param拦截器将尝试ValueStack栈的下一个对象。

把Action和Model隔开

Action作为Controller,应当与Model隔离开,这才是MVC设计模式。

如果Action类实现了ModelDriven接口,该拦截器将把ModelDriven接口的getModel()方法返回的对象置于栈顶。

Action实现ModelDriven接口后的运行流程:

  • 先会执行ModelDrivenInterceptor的intercept方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public String intercept(ActionInvocation invocation) throws Exception {
    // 获取Action对象,即EmpolyeeAction对象,此时该Action已经实现了ModelDriven接口
    // public class EmployeeAction implements RequestAware, ModelDriven<Employee>
    Object action = invocation.getAction();
    // 判断Action是否是ModelDriven的实例
    if (action instanceof ModelDriven) {
    // 强制转换为ModelDriven类型
    ModelDriven modelDriven = (ModelDriven) action;
    // 获取值栈
    ValueStack stack = invocation.getStack();
    // 调用ModelDriven接口的getModel()方法,即调用EmployeeAction的getModel()方法
    /*
    @Override
    public Employee getModel() {
    // TODO Auto-generated method stub
    employee = new Employee();
    return employee;
    }
    */
    Object model = modelDriven.getModel();
    if (model != null) {
    // 把getModel()方法的返回值压入到值栈的栈顶,实际压入的是EmployeeAction的employee成员变量
    stack.push(model);
    }
    if (refreshModelBeforeResult) {
    invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
    }
    }
    return invocation.invoke();
    }
  • 执行ParametersInterceptor的intercept方法:把请求参数的值赋给栈顶对象对应的属性,若栈顶对象没有对应的属性,则查询值栈中下一个对象对应的属性

  • 注意:getModel()方法不能提供以下实现,的确会返回一个Employee对象到值栈的栈顶,但当前Action的employee成员变量却是null:

    1
    2
    3
    4
    5
    @Override
    public Employee getModel() {
    // TODO Auto-generated method stub
    return new Employee();
    }